<template>
  <el-card class="tree-editor" :class="{ 'tree-view': !props.isbtnshow }">
    <template #header>
      <div class="card-header">
        <div></div>
        <el-button
          v-if="props.isbtnshow"
          type="primary"
          @click="addRootNode"
          size="small"
        >
          <el-icon><Plus /></el-icon>添加根节点
        </el-button>
      </div>
    </template>
    <div class="tree-container">
      <el-scrollbar height="600px">
        <!-- <TreeItem
          v-for="node in treeData"
          :key="node.projectId"
          :node="treeData"
          :isbtnshow="props.isbtnshow"
          :projectIdShow="projectIdShow"
          @add-node="handleAddNode"
          @edit-node="handleEditNode"
          @click-node="handleNodeClick"
          @remove-node="handleRemoveNode"
          @drag-node="handleDragNode"
        /> -->
        <TreeItem
          v-if="treeData.length > 0"
          :node="treeData"
          :isbtnshow="props.isbtnshow"
          :projectIdShow="projectIdShow"
          @add-node="handleAddNode"
          @edit-node="handleEditNode"
          @click-node="handleNodeClick"
          @remove-node="handleRemoveNode"
          @drag-node="handleDragNode"
        />
      </el-scrollbar>
    </div>
  </el-card>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import TreeItem from "./treeItem.vue";
import type { TreeNode } from "./treeItem.vue";
import * as projectApi from "@/api/project";

const treeData = ref<TreeNode[]>([]);

const props = defineProps<{
  isbtnshow?: boolean;
}>();

const emit = defineEmits<{
  (e: "click-node", id: string | number): void;
}>();

// 获取树数据
const projectInfoTree = async (frist = false) => {
  const data: any = await projectApi.postProjectInfoTree();
  treeData.value = data;
  if (frist) {
    projectIdShow.value = data[0].projectId;
  }
};
projectInfoTree(true);

// 查找节点及其父节点
const findNode = (
  nodes: TreeNode[],
  id: string | number,
  parent: TreeNode | null = null
): { node: TreeNode | null; parent: TreeNode | null } => {
  for (const node of nodes) {
    if (node.projectId === id) {
      return { node, parent };
    }
    if (node.childrens) {
      const found = findNode(node.childrens, id, node);
      if (found.node) {
        return found;
      }
    }
  }
  return { node: null, parent: null };
};

//默认展开节点
const projectIdShow = ref();

// 添加节点
const handleAddNode = async (parentId: string | number, name: string) => {
  if (parentId === "root") {
    await projectApi.postProjectInfoSave({
      projectName: name,
    });
  } else {
    projectIdShow.value = parentId;

    await projectApi.postProjectInfoSave({
      projectName: name,
      parentProjectId: parentId,
    });
  }
  projectInfoTree();
};

// 编辑节点
const handleEditNode = async (id: string | number, name: string) => {
  await projectApi.projectInfoUpdate({
    projectId: id,
    projectName: name,
  });
  projectInfoTree();
  ElMessage.success("修改成功");
};

//点击节点
const handleNodeClick = (id) => {
  emit("click-node", id);
};

// 删除节点
const handleRemoveNode = async (id: string | number) => {
  await projectApi.projectInfoRemove([id]);
  projectInfoTree();
};

// 添加根节点
const addRootNode = () => {
  ElMessageBox.prompt("请输入根节点名称", "添加根节点", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    inputPattern: /.+/,
    inputErrorMessage: "名称不能为空",
  })
    .then(({ value }) => {
      handleAddNode("root", value);
      ElMessage.success("添加成功");
    })
    .catch(() => {});
};

// 核心排序功能
const handleDragNode = async (
  draggedId: string | number, // 被拖动的节点ID
  targetId: string | number, // 目标节点ID
  position: "before" | "after" | "inner"
) => {
  try {
    // 1. 获取相关节点信息
    const { node: draggedNode } = findNode(treeData.value, draggedId);
    const { node: targetNode, parent: targetParent } = findNode(
      treeData.value,
      targetId
    );

    if (!draggedNode || !targetNode) {
      throw new Error("找不到相关节点");
    }

    // 2. 计算新的父级ID和排序位置
    let newParentId: string | number;
    let newSort: number;
    let siblings: TreeNode[] = [];

    if (position === "inner") {
      // 拖入目标节点内部
      newParentId = targetNode.projectId;
      siblings = targetNode.childrens || [];
      newSort =
        siblings.length > 0 ? siblings[siblings.length - 1].sort + 1 : 0;
    } else {
      // 拖到目标节点前后
      newParentId = targetParent?.projectId || "root";
      siblings = targetParent?.childrens || treeData.value;

      const targetIndex = siblings.findIndex((n) => n.projectId === targetId);
      if (targetIndex === -1) {
        throw new Error("目标节点不在同级列表中");
      }

      if (position === "before") {
        // 拖到目标节点前面
        if (targetIndex === 0) {
          // 如果是第一个节点，则放在最前面
          newSort = siblings[0].sort - 1;
        } else {
          // 否则放在前一个节点和目标节点中间
          newSort =
            (siblings[targetIndex - 1].sort + siblings[targetIndex].sort) / 2;
        }
      } else {
        // 拖到目标节点后面
        if (targetIndex === siblings.length - 1) {
          // 如果是最后一个节点，则放在最后面
          newSort = siblings[targetIndex].sort + 1;
        } else {
          // 否则放在目标节点和后一个节点中间
          newSort =
            (siblings[targetIndex].sort + siblings[targetIndex + 1].sort) / 2;
        }
      }
    }
    projectIdShow.value = newParentId;
    // 3. 调用API更新排序
    await projectApi.projectInfoUpdate({
      projectId: draggedId,
      projectName: draggedNode.projectName,
      parentProjectId: newParentId,
      sort: newSort,
    });

    // 4. 刷新数据
    projectInfoTree();
    ElMessage.success("排序更新成功");
  } catch (error) {
    console.error("排序失败:", error);
    ElMessage.error("排序失败：" + (error as Error).message);
  }
};
</script>

<style scoped lang="scss">
.tree-editor {
  width: 450px;

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .tree-container {
    padding: 10px;
    padding-left: 0;
  }
}
.tree-view {
  width: 300px;
}
</style>
